tyNamespace.MjActions = cc.Class.extend({
    duiCount: 0,

    sort: function (tiles) {
        var sorted = [];
        var currentT = null;
        var compareT = null;
        for (var i = 0; i < tiles.length; i++) {
            currentT = tiles[i];
            currentT.index = i;
            for (var j = i + 1; j < tiles.length; j++) {
                compareT = tiles[j];
                if (compareT != null && (currentT.typeValue * 10 + currentT.num) > (compareT.typeValue * 10 + compareT.num)) {
//					cc.log("i:%d ,j:%d, type ：%s -> %s,num：%d -> %d" , i, j, currentT.type, compareT.type, currentT.num, compareT.num);
                    tiles[i] = compareT;
                    tiles[j] = currentT;
                    currentT = compareT;

                    currentT.index = i;
                }
            }
        }
    },

    isHu: function (theTiles) {
        this.duiCount = 0;

        if (this.qiDuiHu(theTiles))
            return true;

        tyNamespace.haveJiang = false;
        tyNamespace.danPai = null;
        return this.toCheckHu(theTiles);
    },

    qiDuiHu: function (theTiles) {
        var currentT = theTiles[0];

        var haveComp = false;

        var dui = this.checkDui(currentT, theTiles);
        if (dui.length == 2) {
            haveComp = true;
            this.duiCount++;

            var comp = new tyNamespace.Component(tyNamespace.ComponentType.Dui, dui);

            var afterRemove = this.remove(comp, theTiles);

            if (afterRemove.length == 0 && this.duiCount == 7)
                return true;

            if (this.qiDuiHu(afterRemove))
                return true;
        }

        if (!haveComp)
            tyNamespace.danPai = currentT;

        return false;
    },

    toCheckHu: function (theTiles) {
//		var clone = [];
//		clone = clone.concat(theTiles);
//		var tilesString = "[";
//		for (var i = 0; i < clone.length; i++) {
//		var tile = clone[i];
//		tilesString += tile.num + "" + tile.type + ",";
//		}
//		tilesString += "]";
        //
//		cc.log(tilesString);

        var currentT = theTiles[0];

        var haveComp = false;

        var shun = this.checkShun(currentT, theTiles);
        if (shun.length == 3) {
            haveComp = true;

            var comp = new tyNamespace.Component(tyNamespace.ComponentType.Shun, shun);

            var afterRemove = this.remove(comp, theTiles);

            if (afterRemove.length == 0)
                return true;

            if (this.toCheckHu(afterRemove))
                return true;
        }

        //手中的牌不需要判断杠，杠被排除
//		var gang = this.checkGang(currentT, theTiles);
//		if (gang.length == 4) {
//		haveComp = true;

//		var comp = new tyNamespace.Component(tyNamespace.ComponentType.Gang, gang);

//		var afterRemove = this.remove(comp, theTiles);

//		if (afterRemove.length == 0)
//		return true;

//		if (this.toCheckHu(afterRemove))
//		return true;
//		}

        var bao = this.checkBao(currentT, theTiles);
        if (bao.length == 3) {
            haveComp = true;

            var comp = new tyNamespace.Component(tyNamespace.ComponentType.Bao, bao);

            var afterRemove = this.remove(comp, theTiles);

            if (afterRemove.length == 0)
                return true;

            if (this.toCheckHu(afterRemove))
                return true;
        }

        var dui = this.checkDui(currentT, theTiles);
        if (dui.length == 2 && !tyNamespace.haveJiang) {
            haveComp = true;

            var comp = new tyNamespace.Component(tyNamespace.ComponentType.Dui, dui);

            var afterRemove = this.remove(comp, theTiles);

            tyNamespace.haveJiang = true;

            if (afterRemove.length == 0)
                return true;

            if (this.toCheckHu(afterRemove))
                return true;

            tyNamespace.haveJiang = false;
        }

        if (!haveComp)
            tyNamespace.danPai = currentT;

        return false;
    },

    chu: function (theTiles) {
        var clone = [];
        clone = clone.concat(theTiles);
        for (var i = 0; i < clone.length; i++) {
            var currentT = clone[i];

            var gang = this.checkGang(currentT, clone);
            if (gang.length == 4)
                continue;

            var bao = this.checkBao(currentT, clone);
            if (bao.length == 3)
                continue;

            if (this.haveShun(currentT, clone))
                continue;

            var dui = this.checkDui(currentT, clone);
            if (dui.length >= 2)
                continue;

            return currentT;
        }

        return this.simpleChu(theTiles);
    },

    simpleChu: function (theTiles) {
        var clone = [];
        clone = clone.concat(theTiles);

        var currentT = clone[0];

        var gang = this.checkGang(currentT, clone);
        if (gang.length == 4) {
//			cc.log("gang :%d%s", currentT.num, currentT.type);
            var comp = new tyNamespace.Component(tyNamespace.ComponentType.Gang, gang);

            var afterRemove = this.remove(comp, clone);
            if (afterRemove.length <= 0)
                return currentT;

            return this.simpleChu(afterRemove);
        }

        var bao = this.checkBao(currentT, clone);
        if (bao.length == 3) {
//			cc.log("bao :%d%s", currentT.num, currentT.type);
            var comp = new tyNamespace.Component(tyNamespace.ComponentType.Bao, bao);

            var afterRemove = this.remove(comp, clone);
            if (afterRemove.length <= 0)
                return currentT;

            return this.simpleChu(afterRemove);
        }

        var shun = this.checkShun(currentT, clone);
        if (shun.length == 3) {
//			cc.log("shun :%d%s", currentT.num, currentT.type);
            var comp = new tyNamespace.Component(tyNamespace.ComponentType.Shun, shun);

            var afterRemove = this.remove(comp, clone);
            if (afterRemove.length <= 0)
                return currentT;

            return this.simpleChu(afterRemove);
        }

        var dui = this.checkDui(currentT, clone);
        if (dui.length >= 2) {
//			cc.log("dui :%d%s", currentT.num, currentT.type);
            var comp = new tyNamespace.Component(tyNamespace.ComponentType.Dui, dui);

            var afterRemove = this.remove(comp, clone);
            if (afterRemove.length <= 0)
                return currentT;

            return this.simpleChu(afterRemove);
        }

        if (shun.length == 1) {
//			cc.log("shun :%d%s", currentT.num, currentT.type);
            var comp = new tyNamespace.Component(tyNamespace.ComponentType.Shun, shun);

            var afterRemove = this.remove(comp, clone);

            if (afterRemove.length <= 0)
                return currentT;

            return this.simpleChu(afterRemove);
        }

        return currentT;
    },

    checkDui: function (tile, tiles) {
        var dui = [];

        for (var i = 0; i < tiles.length; i++) {
            var currentT = tiles[i];

            if (tile != currentT && currentT.typeValue == tile.typeValue && currentT.num == tile.num && dui.length < 1) {
                dui.push(currentT);
                break;
            }
        }

        if (dui.length == 1)
            dui.push(tile);

        return dui;
    },

    checkBao: function (tile, tiles) {
        var bao = [];

        for (var i = 0; i < tiles.length; i++) {
            var currentT = tiles[i];

            if (tile == null)
                cc.log("dd");

            if (tile != currentT && currentT.typeValue == tile.typeValue && currentT.num == tile.num && bao.length < 2)
                bao.push(currentT);

            if (bao.length == 2)
                break;
        }

        if (bao.length == 2) {
            bao.push(tile);
            return bao;
        }

        bao.splice(0, bao.length);
        return bao;
    },

    checkGang: function (tile, tiles) {
        var gang = [];

        if (tile.status == tyNamespace.TileStatus.Gang || tile.status == tyNamespace.TileStatus.AnGang)
            return gang;

        for (var i = 0; i < tiles.length; i++) {
            var currentT = tiles[i];

            if (tile != currentT && currentT.typeValue == tile.typeValue && currentT.num == tile.num)
                gang.push(currentT);
        }

        if (gang.length == 4)
            return gang;

        if (gang.length == 3) {
            gang.push(tile);
            return gang;
        }

        gang.splice(0, gang.length);
        return gang;
    },

    remove: function (comp, tiles) {
        var compArray = comp.tiles;

        return this.remain(compArray, tiles);
    },

    remain: function (moveTiles, handTiles) {
        var afterRemove = [];
        for (var i = 0; i < handTiles.length; i++) {
            var currentT = handTiles[i];
            if (!this.haveTileByHash(currentT, moveTiles)) {
                afterRemove.push(currentT);
            }
        }

        return afterRemove;
    },

    removeByHash: function (tiles, theTile) {
        for (var i = 0; i < tiles.length; i++) {
            var currentT = tiles[i];
            if (theTile == currentT) {
                tiles.splice(i, 1);
                break;
            }
        }
    },

    checkLeftShun: function (tile, tiles) {
        var shun = [];
        var currentTile = null;

        for (var a = 0; a < tiles.length; a++) {
            if (currentTile == null || currentTile.num != tiles[a].num || currentTile.typeValue != tiles[a].typeValue)
                currentTile = tiles[a];
            else
                continue;
            if (tiles[a].num == tile.num - 2 && tiles[a].typeValue == tile.typeValue)
                shun.push(tiles[a]);
            if (tiles[a].num == tile.num - 1 && tiles[a].typeValue == tile.typeValue) {
                shun.push(tiles[a]);
                shun.push(tile);
            }
        }

        return shun;
    },

    checkMiddleShun: function (tile, tiles) {
        var shun = [];
        var currentTile = null;

        for (var a = 0; a < tiles.length; a++) {
            if (currentTile == null || currentTile.num != tiles[a].num || currentTile.typeValue != tiles[a].typeValue)
                currentTile = tiles[a];
            else
                continue;
            if (tiles[a].num == tile.num - 1 && tiles[a].typeValue == tile.typeValue) {
                shun.push(tiles[a]);
                shun.push(tile);
            }
            if (tiles[a].num == tile.num + 1 && tiles[a].typeValue == tile.typeValue)
                shun.push(tiles[a]);
        }

        return shun;
    },

    checkRightShun: function (tile, tiles) {
        var shun = [];
        var currentTile = null;

        for (var a = 0; a < tiles.length; a++) {
            if (currentTile == null || currentTile.num != tiles[a].num || currentTile.typeValue != tiles[a].typeValue)
                currentTile = tiles[a];
            else
                continue;
            if (tiles[a].num == tile.num + 1 && tiles[a].typeValue == tile.typeValue) {
                shun.push(tile);
                shun.push(tiles[a]);
            }
            if (tiles[a].num == tile.num + 2 && tiles[a].typeValue == tile.typeValue)
                shun.push(tiles[a]);
        }

        return shun;
    },

    checkShun: function (tile, tiles) {
        var shun = [];
        if (tile.num <= 7) {
            var nextTile = new tyNamespace.Tile(tile.typeValue, tile.num + 1);
            nextTile.index = tile.index + 1;

            var nnTile = new tyNamespace.Tile(tile.typeValue, tile.num + 2);

            if (this.getShun(nextTile, nnTile, tiles, shun)) {
                shun.push(tile);
                return shun;
            }
        }

        return shun;
    },

    haveShun: function (tile, tiles) {
        for (var i = 0; i < tiles.length; i++) {
            var currentT = tiles[i];

            if (tile != currentT && currentT.typeValue == tile.typeValue && Math.abs(currentT.num - tile.num) <= 2)
                return true;
        }

        return false;
    },

    getShun: function (fTile, sTile, tiles, shun) {
        for (var i = 0; i < tiles.length; i++) {
            var currentT = tiles[i];

            if (currentT.typeValue == fTile.typeValue && currentT.num == fTile.num && !tyNamespace.MjActions.haveTheTile(currentT, shun))
                shun.push(currentT);

            if (currentT.typeValue == sTile.typeValue && currentT.num == sTile.num && !tyNamespace.MjActions.haveTheTile(currentT, shun))
                shun.push(currentT);

            if (shun.length == 2)
                break;
        }

        return shun.length == 2;
    },

    haveTheTile: function (tile, tiles) {
        return this.getTileIndex(tile, tiles) >= 0;
    },

    haveTileByHash: function (tile, tiles) {
        return this.haveTileIndexByHash(tile, tiles) >= 0;
    },

    getTileIndex: function (tile, tiles) {
        for (var i = 0; i < tiles.length; i++) {
            var currentT = tiles[i];

            if (currentT.typeValue == tile.typeValue && currentT.num == tile.num)
                return i;
        }

        return -1;
    },

    haveTileIndexByHash: function (tile, tiles) {
        for (var i = 0; i < tiles.length; i++) {
            var currentT = tiles[i];

            if (currentT.id == tile.id)
                return i;
        }

        return -1;
    },

    getTileByNum: function (number) {
        if (number == 0x00)
            return null;

        var tileType = parseInt(number / 0x10);
        var tileNum = number % 0x10;

//		cc.log("tileNum:" + tileNum + ",tileType:" + tileType);

        return new tyNamespace.Tile(tileType, tileNum);
    },

    getNumByTile: function (tile) {
        if (tile == null)
            return 0;

        var typeValue = tile.typeValue;
        var num = tile.num;

        return num + typeValue * 0x10;
    },


    pushTile: function (tiles, tile) {
        if (!this.haveTheTile(tile, tiles))
            tiles.push(tile);
    },

    canHu: function (tiles, tile) {
        var clone = [];
        clone = clone.concat(tiles);
        clone.push(tile);

        tyNamespace.MjActions.sort(clone);

        return this.isHu(clone);
    },

    getTingTiles: function (tile, tiles) {
        var restTiles = [];
        for (var a = 0; a < tiles.length; a++) {
            if (tiles[a].index != tile.index)
                restTiles.push(tiles[a].getCopy());
        }

        this.sort(restTiles);

        var clone = [];
        for (var b = 0; b < restTiles.length; b++) {
            tyNamespace.MjActions.pushTile(clone, restTiles[b].getCopy(this.player));
            if (restTiles[b].num == 1) {
                tyNamespace.MjActions.pushTile(clone, restTiles[b].getCopy(this.player, 1));
            }
            else if (restTiles[b].num == 9) {
                tyNamespace.MjActions.pushTile(clone, restTiles[b].getCopy(this.player, -1));
            }
            else {
                tyNamespace.MjActions.pushTile(clone, restTiles[b].getCopy(this.player, -1));
                tyNamespace.MjActions.pushTile(clone, restTiles[b].getCopy(this.player, 1));
            }
        }

        this.sort(clone);

        var tingTiles = [];
        for (var c = 0; c < clone.length; c++) {
            if (this.canHu(restTiles, clone[c]))
                tingTiles.push(clone[c]);
        }

        for(var i = 0; i < tingTiles.length; i ++){
            cc.log("第" + i + "个可胡的牌:" + tingTiles[i].num + "-" + tingTiles[i].type);
        }

        return tingTiles;
    }

});

tyNamespace.MjActions = new tyNamespace.MjActions();

tyNamespace.haveJiang = false;
tyNamespace.danPai = null;
